package com.template.web.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;

public class JwtUtil {

    private static final String SECRET = "shiro@template";

    // 过期时间30分钟
    private static final long EXPIRE_TIME = 30 * 60 * 1000;

    /**
     * 校验token是否正确
     *
     * @param token  密钥
     * @return 是否正确
     */
    public static boolean verify(String token) {
        try {
            // 根据密钥（这里是密码）生成一个算法实例
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            // 生成JWT效验器
            JWTVerifier verifier = JWT.require(algorithm) // 设置一个以该算法为基础的校验器
                    .build(); // 创建校验器
            // 效验TOKEN，如果出现不匹配，就会出现异常
            verifier.verify(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @param token  密钥
     * @return token中包含的用户名
     */
    public static String getUsername(String token) {
        try {
            // 对token进行解码
            DecodedJWT jwt = JWT.decode(token);
            // 获取解码信息中的username
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 生成token签名EXPIRE_TIME分钟后过期
     *
     * @param id 用户id
     * @param username 用户名
     * @return 加密的token
     */
    public static String sign(String id, String username) {
        // 现在系统的时间 + 过期时间
        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
        // 根据密钥（这里是密码）生成一个算法实例
        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        // 附带username信息
        return JWT.create()
                .withClaim("id", id)
                .withClaim("username", username) // payload 存储非敏感的信息 例如用户账号，不能存密码，防止被人解析
                .withExpiresAt(date) // 指定令牌的过期时间
                .sign(algorithm); // 签名  保密复杂
    }

    public static void main(String[] args) {
        String s = sign("1", "admin");
        System.out.println(s);
        System.out.println(verify("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNjk1ODAwNTM1fQ.jvfkVQ-uFLSTdw3aSNhKr10-E4dI22aqbnFMIvaFOIU"));
    }
}
